﻿using System;
using System.Windows.Forms;
using StackoverflowNotifier.Properties;
using System.Collections.Generic;
using System.Net;

namespace StackoverflowNotifier
{
    public partial class UserDetailsForm : Form
    {
        private readonly StackOverflowClient.StackOverflowClient client;
        private List<string> notifications = new List<string>();
        private readonly object NotifySync = new object();
        private SetUserForm setUserForm;
        private SetProxyForm setProxyForm;

        public UserDetailsForm()
        {
            InitializeComponent();

            setUserForm = new SetUserForm();
            setProxyForm = new SetProxyForm();

            client = new StackOverflowClient.StackOverflowClient();
            client.userDetailsChanged += client_userDetailsChanged;
            client.userReputationChanged += client_userReputationChanged;
            client.userBadgeNumberChanged += client_userBadgeChanaged;
        }

        void client_userDetailsChanged(StackOverflowClient.UserDescriptor user)
        {
            lblUserName.Text = user.Name;
            lblCurrentReputation.Text = user.Reputation.ToString();
            pictureBox1.ImageLocation = user.Image;

            Notify(string.Format("User {0} Loaded Successfully", user.Name));
            notifyIcon1.Text = string.Format("{0}: {1}", user.Name, user.Reputation);
            Update();
        }

        void client_userReputationChanged(int oldReputation, int newReputation)
        {
            string notificationString = string.Format("Reputation changed to {0} ({1})", newReputation, newReputation - oldReputation);
            Notify(notificationString);

            lblCurrentReputation.Text = newReputation.ToString();
            notifyIcon1.Text = string.Format("{0}: {1}", lblUserName.Text, newReputation);
            Update();
        }

        void client_userBadgeChanaged(int oldValue, int newValue)
        {
        	string notificationString = string.Format("You were awarded additional {0} badge(s))", newValue - oldValue);
            Notify(notificationString);

            Update();
        }
        
        private void Notify(string notificationString)
        {
            Log(notificationString);

            lock (NotifySync)
            {
                notifications.Add(notificationString);
            }
        }

        private void Log(string message)
        {
            if (lstBxLog.Items.Count > 100)
            {
                for (int i = 0; i < 50; i++)
                {
                    lstBxLog.Items.RemoveAt(lstBxLog.Items.Count - 1);
                }   
            }
            lstBxLog.Items.Insert(0, DateTime.Now.ToShortTimeString() + ": " + message);
        }

        internal void LoadUrlDetails()
        {
            string userUrl = Settings.Default.UserURL;
            client.Proxy = setProxyForm.Proxy;

            if (string.IsNullOrEmpty(userUrl))
            {
                MessageBox.Show("User URL is empty - use valid URL",
                    "Bad User URL",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

                return;
            }

            var userDescriptor = client.IsValid(userUrl);
            if (userDescriptor == null)
            {
                MessageBox.Show("Invalid user URL or Proxy\n1. Check that your proxy settings are currect\n2. Copy and paste the url of your user details web page",
                    "Bad User URL",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

                return;
            }

            client.Url = userUrl;
            client.Start(userDescriptor);
        }

        private void UserDetailsForm_Load(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(Settings.Default.UserURL) == false)
            {
                LoadUrlDetails();
                Hide();
                Update();
            }
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            Hide();
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Show();
            contextMenuStrip1.Hide();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Exit();
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Show();
        }

        private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                contextMenuStrip1.Show();
            }
        }

        private void txtBxUserURL_TextChanged(object sender, EventArgs e)
        {

        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Exit();
        }

        private void Exit()
        {
            notifyIcon1.Visible = false;
            client.Stop();
            Application.Exit();
        }

        private void notificationTimer_Tick(object sender, EventArgs e)
        {
            List<string> currentNotification;
            lock (NotifySync)
            {
                if (notifications.Count == 0)
                {
                    return;
                }
                currentNotification = notifications;
                notifications = new List<string>();
            }

            notifyIcon1.BalloonTipTitle = "StackOverflow Notifier";
            notifyIcon1.BalloonTipText = string.Empty;
            foreach (string notifyString in currentNotification)
            {
                notifyIcon1.BalloonTipText += notifyString + "\n";
            }
            notifyIcon1.ShowBalloonTip(10000);
        }
        
        void SetUserToolStripMenuItemClick(object sender, EventArgs e)
        {
            if (setUserForm.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            LoadUrlDetails();
        }

        private void proxySetupToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (setProxyForm.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            LoadUrlDetails();
        }
    }
}
